package com.ruoyi.app.controller.common.service.impl;

import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.app.common.utils.ApiSpaceUtils;
import com.ruoyi.app.controller.common.service.IApiAsyncNotifyService;
import com.ruoyi.app.controller.message.mapper.IAppletTemplateLogMapper;
import com.ruoyi.app.controller.message.service.IAppletTemplateService;
import com.ruoyi.app.controller.order.mapper.IShopOrderAnnounceMapper;
import com.ruoyi.app.controller.shop.mapper.IShopConfigMapper;
import com.ruoyi.app.controller.shop.service.IShopAppletService;
import com.ruoyi.common.constant.*;
import com.ruoyi.common.entity.BO.SmsSendBO;
import com.ruoyi.common.entity.DO.AppletTemplateLogDO;
import com.ruoyi.common.entity.DO.ShopOrderAnnounceDO;
import com.ruoyi.common.entity.DO.shop.ShopAppletDO;
import com.ruoyi.common.entity.VO.shop.ShopConfigSearchVO;
import com.ruoyi.common.entity.VO.shop.ShopConfigVO;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.NumberUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.lianlu.LianluSmsUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service("AsyncNotifyServiceImpl")
@Slf4j
public class ApiAsyncNotifyServiceImpl implements IApiAsyncNotifyService {

    @Value("${applet.miniprogram_state}")
    private String miniprogramState;

    @Value("${applet.lang}")
    private String lang;

    @Value("${applet.accessTokenUrl}")
    private String accessTokenUrl;

    @Value("${applet.templateUrl}")
    private String appletTemplateUrl;

    @Resource
    private IAppletTemplateService appletTemplateService;

    @Resource
    private IShopAppletService shopAppletService;

    @Resource
    private IAppletTemplateLogMapper appletTemplateLogMapper;

    @Resource
    private IShopConfigMapper shopConfigMapper;

    @Resource
    private IShopOrderAnnounceMapper shopOrderAnnounceMapper;

    public void sendWechatTemplateNotify(HashMap<String, String> params) {
        Long shopId = Long.valueOf(params.get("shopId"));
        String configVal = shopConfigMapper.searchValueByKey(SysConfigConstants.ShopConfigEnum.WXNOTIFY_SWITCH.getKey(),shopId);
        if(!UserConstants.YES.equals(configVal)){
            return;
        }
        configVal = shopConfigMapper.searchValueByKey("wxnotify."+params.get("templateKey"),shopId);
        if(!UserConstants.YES.equals(configVal)){
            return;
        }
        String templateId = appletTemplateService.selectTemplateIdByKey(params.get("templateKey"));
        if (StringUtils.isEmpty(templateId)) {
            log.error("无效模板键值，KEY：" + params.get("templateKey"));
        }
        JSONObject queueObj = new JSONObject();
        queueObj.put("touser", params.get("openid"));
        queueObj.put("template_id", templateId);
        queueObj.put("miniprogram_state", miniprogramState);
        queueObj.put("lang", lang);
        switch (params.get("templateKey")) {
            case "recharge":
                queueObj.put("page", "pages/mine/consumption-history/index");
                queueObj.put("data", appletTemplateService.getRechargeSuccessNotifyTemplateData(params));
                break;
            case "petrol":
                queueObj.put("page", "pages/mine/consumption-history/index");
                queueObj.put("data", appletTemplateService.getPetrolSuccessNotifyTemplateData(params));
                break;
            case "balanceChange":
                queueObj.put("page", "pages/mine/consumption-history/index");
                queueObj.put("data", appletTemplateService.getBalanceChangeNotifyTemplateData(params));
                break;
            case "couponReceive":
                queueObj.put("page", "pages/memberCoupon/coupon");
//                queueObj.put("data", appletTemplateService.getCouponInfo(Long.valueOf(params.get("id"))));
                break;
            case "couponExpire":
                queueObj.put("page", "pages/member/winRecord");
//                queueObj.put("data", appletTemplateService.getCouponInfo(Long.valueOf(params.get("id"))));
                break;
            default:
                log.error("无处理，KEY：" + params.get("templateKey"));
                break;
        }
        AppletTemplateLogDO appletTemplateLogDO = new AppletTemplateLogDO();
        appletTemplateLogDO.setTouser(queueObj.get("touser").toString());
        appletTemplateLogDO.setTemplateId(queueObj.get("template_id").toString());
        appletTemplateLogDO.setPage(queueObj.get("page").toString());
        appletTemplateLogDO.setMiniprogramState(queueObj.get("miniprogram_state").toString());
        appletTemplateLogDO.setLang(queueObj.get("lang").toString());
        appletTemplateLogDO.setData(queueObj.get("data").toString());
        appletTemplateLogDO.setCreateTime(new Date());
//        log.info("请求数据:" + queueObj.toString());
        doSendWechatTemplateNotify(Long.valueOf(params.get("shopId")), queueObj.toString());
        appletTemplateLogMapper.insertSelective(appletTemplateLogDO);
    }

    @Override
    public void sendSmsNotify(HashMap<String, String> params) {
        Long shopId = Long.valueOf(params.get("shopId"));
        String configVal = shopConfigMapper.searchValueByKey(SysConfigConstants.ShopConfigEnum.SMSNOTIFY_SWITCH.getKey(),shopId);
        if(!UserConstants.YES.equals(configVal)){
            return;
        }
        configVal = shopConfigMapper.searchValueByKey("smsnotify."+params.get("templateKey"),shopId);
        if(!UserConstants.YES.equals(configVal)){
            return;
        }
        //获取短信内容 替换短信变量
        LianLuSmsConstants.TemplateEnum templateEnum = LianLuSmsConstants.TemplateEnum.match(params.get("templateKey"));
        SmsSendBO smsSendBO = new SmsSendBO();
        smsSendBO.setNotify(true);
        smsSendBO.setPhoneNumberArr(new String[]{params.get("phone")});
        smsSendBO.setTemplateCode(templateEnum.getTemplateId());
        smsSendBO.setTemplateParamArr(params.get("smsVar").split(","));
        log.info("请求数据:" + JSONObject.toJSONString(smsSendBO));
        try{
            LianluSmsUtils.templateSend(smsSendBO);
        }catch (Exception e){
            e.printStackTrace();
            log.info("发送联麓短信失败！:" + JSONObject.toJSONString(smsSendBO));
        }
    }

    @Override
    public void sendAnnounceNotify(HashMap<String, String> params) {
        try{
            ShopOrderAnnounceDO shopOrderAnnounceDO = new ShopOrderAnnounceDO();
            shopOrderAnnounceDO.setShopId(Long.valueOf(params.get("shopId")));
            shopOrderAnnounceDO.setAnnSn(params.get("annSn"));
            shopOrderAnnounceDO.setOrderType(SysConfigConstants.SystemModuleEnum.PETROL.getValue());
            shopOrderAnnounceDO.setOrderSn(params.get("orderSn"));
            shopOrderAnnounceDO.setAnnTitle(params.get("annTitle"));
            shopOrderAnnounceDO.setAnnContent("");
            shopOrderAnnounceDO.setCreateBy("用户支付回调");
            shopOrderAnnounceDO.setCreateTime(new Date());
            shopOrderAnnounceMapper.insertSelective(shopOrderAnnounceDO);
        }catch (Exception e){
            e.printStackTrace();
            log.error("插入语音通知失败！");
        }
    }

    private void doSendWechatTemplateNotify(Long shopId, String queueJsonStr) {
        //TODO：查询店铺的appId和secret
        ShopAppletDO shopApplet = shopAppletService.getDetailByShopId(shopId);
        if (shopApplet == null || shopApplet.getIsEnable() == null || shopApplet.getIsDelete() == 1) {
            throw new BusinessException("请联系运营平台重新开通小程序！");
        }
        if (shopApplet.getIsEnable() == 0) {
            throw new BusinessException("请联系运营平台重新上架小程序！");
        }
        RestTemplate restTemplate = new RestTemplate();
        String resultStr = restTemplate.getForObject(accessTokenUrl, String.class, shopApplet.getAppletAppId(), shopApplet.getAppletSecret(), "client_credential");
        if (StringUtils.isEmpty(resultStr)) {
            throw new BusinessException("网络异常，请稍后再试！");
        }
        try {
            JSONObject resultObj = JSONObject.parseObject(resultStr);
            if (resultObj.containsKey("errcode") && resultObj.getIntValue("errcode") != 0) {
                throw new BusinessException("网络异常，请稍后再试！");
            }
            String accessToken = resultObj.getString("access_token");
            HttpHeaders headers = new HttpHeaders();
            headers.add("Accept", MediaType.APPLICATION_JSON_UTF8_VALUE);
            restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
            HttpEntity<String> formEntity = new HttpEntity<String>(queueJsonStr, headers);
            resultStr = restTemplate.postForEntity(appletTemplateUrl + accessToken, formEntity, String.class).getBody();
            if (StringUtils.isEmpty(resultStr)) {
                throw new BusinessException("网络异常，请稍后再试！");
            }
            resultObj = JSONObject.parseObject(resultStr);
            if (resultObj.containsKey("errcode") && resultObj.getIntValue("errcode") != 0) {
                log.error(resultObj.getString("errcode") + ":" + resultObj.getString("errmsg"));
            }
        } catch (JSONException e) {
//            e.printStackTrace();
            throw new BusinessException("访问小程序服务器超时，请稍后再试！");
        }
    }
}
